移动设备软键盘操作

实际

全屏的时候也需要输入,无法获得输入框的高度;功能上不能把input放顶端,包括非全屏的时候不在顶端
假的input框需要计算位置/获取光标/文本内容/控制显示等

故:
非全屏的时候,利用移动设备原生功能scorllIntoView自己滚动;没有做处理。
全屏的时候,获取焦点后设置输入框位置到顶端;失去焦点后再去除顶端位置的className
不是很漂亮的地方:input很容易失去焦点,以致input的位置来回移动

需要利用移动设备的输入功能,包括不同地区的语言/表情/数字/输入法等,模拟移动键盘是想得多了。
后:colleague利用全屏时逻辑改动非全屏时,整个聊天区域到直播区,以防止直播内容被顶出视窗。失去焦点设置iframe返回原位置

# js对手机软键盘的监听
原文: http://www.cnblogs.com/hefenghefeng/p/7003152.html

js还没有办法对手机软键盘直接进行监听的,但是可以有其他角度来判断软键盘是否弹起。比如输入框是否获取焦点等。

ios: focusin和focusout

focusin和focusout支持冒泡,对应focus和blur,
使用focusin和focusout的原因是focusin和focusout可以冒泡,focus和blur不会冒泡,这样就可以使用事件代理,处理多个输入框存在的情况。

1
2
3
4
5
6
$(document).on('focusin', function () {
  //软键盘弹出的事件处理
});
$(document).on('focusout', function () {
  //软键盘收起的事件处理
});

android: window resize

但是,实际中发现这种方法仅在ios上有效,键盘弹出和键盘收起与输入框的focusin和focusout一一对应。
在android中,点击键盘上的收起按钮,键盘虽然收起了,输入框仍然处于焦点状态,并没有触发focusout事件。

经实践,发现一种变通的方法。通过比较window resize后的clientHeight与最初进来页面时的clientHeight进行对比,如果小于最初的值,那么就可以认为是键盘弹出,否则,认为键盘收起。

在android中键盘弹出和收起会改变window的高度,因此监听window的resiz

1
2
3
4
5
6
7
8
9
10
var clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
$(window).on('resize', function () {
var nowClientHeight = document.documentElement.clientHeight || document.body.clientHeight;
if (clientHeight > nowClientHeight) {
//键盘弹出的事件处理
}
else {
//键盘收起的事件处理
}
});

或许有人问,ios为什么不用android的解决方式呢?因为ios的第三方键盘可能并不会导致window resize,所以无效。

附一张移动端webview对focusin、focusout的支持情况。

# [移动端输入框填坑系列一]
## textarea置底展示问题-获取高度,设置假input的位置

可以看出,键盘会将页面顶上去。那么如果希望可以将输入框和键盘完全贴合,我们可以使用div模拟一个假的输入框,使用定位将真正的输入框隐藏掉,当点击假的输入框的时候,将真正的输入框定位到键盘上方,并且手动获取输入框焦点。

在实现过程中需要注意下面几个问题:
1、真正的输入框的位置计算:
2、在ios下手动获取焦点不可以用click事件,需要使用tap事件才可以手动触发
3、当键盘收起的时候我们需要将真输入框再次隐藏掉,除了使用失去焦点(blur)方法,还有什么方法可以判断键盘是否收起呢?
4、因为textarea中的文字不能置底显示,当输入超过一行textarea需要自动调整高度

$_PS: 假input的有点复杂,有许多问题需要注意,没有上面的简单直接

# [ 如何用 js 获取虚拟键盘高度?(适用所有平台)]

软键盘把输入框遮挡

1. 第一个是通过把 input 布局尽量放在页面顶部,显然这个不是我们想要的,否决掉
2. 把 input 放在最底部,用来完成 footer 固定的效果,但是要局限页面高度不超过窗口高度,我们可以通过自制滚动控件来解除这个限制,那现在需要解决的技术点就变为实现一个模拟滚动控件
3. 通过比对软键盘弹出前后的 window.innerHeight 的高度差来得到键盘高度,从而根据这个高度来实现底部定位和输入剧中,但是该方法局限于不同设备平台的支持

### 针对 第二种方案 的限制
输入框定位在页面的最底部,当软键盘弹起时整个视图窗口页面向上卷动,到达最底部时停止。
这是因为当你首次 fouse 到输入框的时候软键盘弹出,浏览器会使页面会向上滚动,以确保 input 是可见的,该特性和 document.body.scrollIntoViewIfNeeded 方法是一致的,

1. 但是当你 body 的可滚动高度超过窗口高度时还会产生另一个问题:固定元素将随页面滚动 如下图:
因此浏览器关心的只是 input 是否被覆盖?实际上是 input 中的光标位置!那么这就解释了为什么输入框在底部的时候刚好勉强完成了,因为 input 在页面的底部时,软键盘弹出势必会遮挡住 input,因而浏览器会向上滚动至输入框可见的位置。

2. 但是如下图的效果这样就无法做到了,因为在输入框的下面还有一行工具栏,也就是说输入框并非在最底部的位置,那么浏览器在滚动到可视位置时只会确保到 input 可见,而对于工具栏是否可见则并不在浏览器的考虑范围内。

## IOING 的解决方案分析

## 用js 获取键盘高度的方法
$_PS: andriod试过,没有这些个API

1
2
3
4
5
6
7
8
9
10
//键盘弹起时为键盘高度,未弹起时为0
console.log(window.keyboard.height)
// 通过键盘弹起事件获取
window.on('keyboardup', function (e) {
console.log(e.height)
})
// 键盘收起事件
window.on('keyboarddown', function (e) {
console.log(e.height) // 0
})

# [移动端H5输入框、光标、数字键盘全假套件实现]

其它:
移动web页面,input获取焦点弹出系统虚拟键盘时,挡住input,求解决方案?

knowledge is no pay,reward is kindness
0%